﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ArgusLight.Fractals2D
{
	/// <summary>
	/// Any class which derives from <see cref="FractalParameter"/> is expected to be seriazable
	/// with <see cref="XmlSerializer"/>. If the class contains Members, which are not by default
	/// seriazable with XmlSerializer, the class must implement <see cref="IXmlSerializable"/>.
	/// </summary>
	public class FractalParameter
	{
		public double Rotation { get; set; }
		public int PixelWidth { get; set; }
		public int PixelHeight { get; set; }

		public FractalParameter()
		{
		}

		public virtual FractalParameter GetCopy()
		{
			return this.GetCopy<FractalParameter>();
		}

		public T GetCopy<T>() where T : FractalParameter, new()
		{
			T t = new T();
			Type type = typeof(T);
			PropertyInfo[] pis = this.GetType().GetProperties();
			foreach (PropertyInfo pi in pis)
			{
				PropertyInfo p = type.GetProperty(pi.Name);
				if (p == null || p.PropertyType != pi.PropertyType)
					continue;
				pi.SetValue(t, pi.GetValue(this, null), null);
			}
			return t;
		}

		public void XmlSerialize(Stream stream)
		{
			XmlSerializer xs = new XmlSerializer(this.GetType());
			xs.Serialize(stream, this);
		}

		public static FractalParameter XmlDeserialize(Type FractalParameterType, Stream stream)
		{
			XmlSerializer xs = new XmlSerializer(FractalParameterType);
			return (FractalParameter)xs.Deserialize(stream);
		}
	}
}
